﻿using Microsoft.Extensions.Options;
using Minio.AspNetCore;
using Minio;
using System.IO;
using System.Text.Json;
using System.Text.Json.Nodes;

namespace MinioStorage
{
    public interface IMinIOService
    {
        /// <summary>
        /// 上传
        /// </summary>
        /// <param name="file">文件</param>
        /// <returns></returns>
        Task<Result<FileModel>> UploadAsync(FormFileCollection file);

        /// <summary>
        /// 上传图片
        /// </summary>
        /// <param name="file">文件</param>
        /// <returns></returns>

        Task<Result<FileModel>> UploadImageAsync(FormFileCollection file);

        /// <summary>
        /// 上传pdf
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        Task<Result<FileModel>> UploadPdf(Stream file);
    }

    /// <summary>
    /// 上传文件相关
    /// </summary>
    public class MinIOService : IMinIOService
    {
         
        public MinioClient _client { get; set; }
        public MinioOptions _minioOptions { get; set; }
        public MinIOService( MinioClient client, IOptions<MinioOptions> minioOptions)
        {
            _client = client;
            _minioOptions = minioOptions.Value;
        }
        //获取图片的返回类型
        public static Dictionary<string, string> contentTypDict = new Dictionary<string, string> {
               {"bmp","image/bmp" },
               {"jpg","image/jpeg"},
               {"jpeg","image/jpeg"},
               {"jpe","image/jpeg"},
               {"png","image/png"},
               {"gif","image/gif"},
               {"ico","image/x-ico"},
               {"tif","image/tiff"},
               {"tiff","image/tiff"},
               {"fax","image/fax"},
               {"wbmp","image//vnd.wap.wbmp"},
               {"rp","image/vnd.rn-realpix"} };


        /// <summary>
        /// 上传图片
        /// </summary>
        /// <param name="file">文件</param>
        /// <returns></returns>

        public async Task<Result<FileModel>> UploadImageAsync(FormFileCollection file)
        {
            Result<FileModel> res = new Result<FileModel>(false, "上传失败");

            //获得文件扩展名
            string fileNameEx = System.IO.Path.GetExtension(file[0].FileName).Replace(".", "");

            //是否是图片，现在只能是图片上传 文件类型 或扩展名不一致则返回
            if (contentTypDict.Values.FirstOrDefault(c => c == file[0].ContentType.ToLower()) == null 
                || contentTypDict.Keys.FirstOrDefault(c => c == fileNameEx) == null)
            {
                res.Msg = "图片格式不正确";
                return res;
            }
            else
                return await UploadAsync(file);
        }


        public readonly string BucketName = "omsfile";
        public readonly string FileURL = "http://127.0.0.1:9000/file";
        public readonly string ContentRootPath = "C:\\Users\\Administrator\\Desktop\\新建文件夹\\MinioStorage";
        /// <summary>
        /// 上传
        /// </summary>
        /// <param name="file">文件</param>
        /// <returns></returns>

        public async Task<Result<FileModel>> UploadAsync(FormFileCollection file)
        {
            Result<FileModel> res = new Result<FileModel>(false, "上传失败");



            try
            {

                //存储桶名
                string bucketName = BucketName;

                FileModel fileModel = new FileModel();
                await CreateBucket(bucketName);
                var newFileName = CreateNewFileName(bucketName, file[0].FileName);
                await _client.PutObjectAsync(bucketName, newFileName, file[0].OpenReadStream(), file[0].Length,
                    file[0].ContentType);
                fileModel.Url = $"{FileURL}{newFileName}";

                //是否是图片，是图片进行压缩
                if (contentTypDict.Values.Contains(file[0].ContentType.ToLower()))
                {
                    string path = $"{ContentRootPath}/wwwroot/imgTemp/";
                    if (!Directory.Exists(Path.GetDirectoryName(path)))
                        Directory.CreateDirectory(Path.GetDirectoryName(path));

                    var bImageName = $"{newFileName}";
                    var savepath = $"{path}{newFileName}";//保存绝对路径
                    #region 保存原图到本地
                    using (FileStream fs = System.IO.File.Create(path + newFileName))
                    {
                        file[0].CopyTo(fs);
                        fs.Flush();
                    }
                    #endregion

                    //#region 保存缩略图到本地
                    //var bUrlRes = TencentCloudImageHelper.GetThumbnailImage(240, newFileName, path);
                    //#endregion

                    //上传压缩图

                    using (var sw = new FileStream(savepath, FileMode.Open))
                    {
                        await _client.PutObjectAsync(bucketName, bImageName, sw, sw.Length,
             "image/jpeg");
                        fileModel.Url = $"{FileURL}{bImageName}";
                    }

                    if (Directory.Exists(Path.GetDirectoryName(path)))
                        Directory.Delete(Path.GetDirectoryName(path), true);

                }
                res.IsSuccess = true;
                res.Msg = "上传成功";
                res.Data = fileModel;
                return res;
            }
            catch (Exception e)
            {

                return res;
            }
        }

        public async Task<Result<FileModel>> UploadPdf(Stream file)
        {
            Result<FileModel> res = new Result<FileModel>(false, "上传失败");
            try
            {

                //存储桶名
                string bucketName = BucketName;

                FileModel fileModel = new FileModel();
                await CreateBucket(bucketName);
                var newFileName = CreateNewFileName(bucketName, "授权书.pdf");
                await _client.PutObjectAsync(bucketName, newFileName, file, file.Length,
                    "application/pdf");
                fileModel.Url = $"{FileURL}{newFileName}";

                res.IsSuccess = true;
                res.Msg = "上传成功";
                res.Data = fileModel;
                return res;
            }
            catch (Exception e)
            {

                return res;
            }
        }

        private async Task CreateBucket(string bucketName)
        {
            var found = await _client.BucketExistsAsync(bucketName);
            if (!found)
            {
                await _client.MakeBucketAsync(bucketName);
                //设置只读策略
                var pObj = new
                {
                    Version = "2012-10-17",
                    Statement = new[]
                    {
                       new
                       {
                           Effect = "Allow",
                           Principal = new
                           {
                               AWS = new [] {"*"}
                           },
                           Action = new [] {"s3:GetBucketLocation", "s3:ListBucket"},
                           Resource = new []
                           {
                               $"arn:aws:s3:::{bucketName}"
                           }
                       },
                       new
                       {
                           Effect = "Allow",
                           Principal = new
                           {
                               AWS = new [] {"*"}
                           },
                           Action = new [] {"s3:GetObject"},
                           Resource = new []
                           {
                               $"arn:aws:s3:::{bucketName}/*"
                           }
                       }
                   }
                };
                var po = JsonSerializer.Serialize(pObj);
                await _client.SetPolicyAsync(bucketName, po);
            }
        }

        private string CreateNewFileName(string bucketName, string oldFileName)
        {
            var dt = Guid.NewGuid().ToString().Replace("-", "").Substring(10) + DateTimeOffset.Now.ToUnixTimeSeconds();
            var extensions = Path.GetExtension(oldFileName);
            var newFileName = $"{bucketName}-{dt}{extensions}";
            return newFileName;
        }
    }
    public static class FeatureValuesHelper
    {
        #region 获取featurevalues 对应的value值
        /// <summary>
        /// 
        /// </summary>
        /// <param name="featureValues"></param>
        /// <returns></returns>
        public static JsonObject ToFeatureValuesConvertJson(this string featureValues)
        {
            var keyValuePairs = new JsonObject();
            try
            {

                if (string.IsNullOrEmpty(featureValues))
                {
                    return keyValuePairs;
                }

                var objects = featureValues.Split(';');
                foreach (var item in objects)
                {
                    var curObject = item.Split(":");
                    if (curObject.Any())
                    {
                        keyValuePairs.Add(curObject.FirstOrDefault(), curObject.LastOrDefault());
                    }
                }

                return keyValuePairs;
            }
            catch (Exception ex)
            {
                keyValuePairs.Add("erroe", ex.Message);
                return keyValuePairs;
            }

        }
        #endregion
    }
    public class Result<T>
    {
        public Result(bool isSuccess, string msg)
        {
            this.IsSuccess = isSuccess;
            this.Msg = msg;

        }
        public bool IsSuccess { get; set; }
        public string Code { get; set; }
        public string Msg { get; set; }
        /// <summary>
        /// 返回数据列表
        /// </summary>
        public Object Data { set; get; }
    }
    public class FileModel
    {
        public string Url { get; set; }
    }
}
